#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>

class Task;
using namespace std;
using ElemType = Task *;

class TaskQueue
{
public:
    TaskQueue(size_t capa);
    TaskQueue(const TaskQueue &rhs) = delete;
    TaskQueue operator=(const TaskQueue &rhs) = delete;

    ~TaskQueue();

    // 生产与消费
    void push(ElemType ptask);
    ElemType pop();

    bool full() const;
    bool empty() const;
    int size() const;
    void weakup(); // 唤醒所有等待在_notEmpty()条件变量上的线程

private:
    size_t _capacity;
    queue<ElemType> _que;
    mutex _mtx;
    condition_variable _notFull;  // 生产者
    condition_variable _notEmpty; // 消费者
    bool _flag;                   // 标识
};